/****************************************************************************

	COPYRIGHT(C) MAXSI SOFTWARE, JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010, 2010

    This file is part of Maxsi Engine.

    Maxsi Engine is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Maxsi Engine is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Maxsi Engine. If not, see <http://www.gnu.org/licenses/>.

	*/ #include "MaxsiEngineContributors.h" /*

	If you modify this file, please enter your name below and provide contact
	information in MaxsiEngineContributors.h. For more information please see
	MaxsiEngineContributors.h.
	
	Contributors to this file:

	- Jonas 'Sortie' Termansen
	- [your name here]

	MaxsiEngine.dll
	A linkable version of Maxsi Engine

	MaxsiUI_Controls.h
	Functions for easily creating common controls

****************************************************************************/



#include <windowsx.h>
#include "MaxsiEngine.h"
#include "commctrl.h"

#ifndef __MINGW_H
#pragma warning( disable : 4312 )
#endif

namespace MaxsiEngine
{
	bool MaxsiUI_Controls_Initialized = false;

	LINK bool InitializeMaxsiUI_Controls(HANDLE hInstance)
	{
		if ( MaxsiUI_Controls_Initialized ) { return true; }
		if ( !MaxsiUI_Control_Label_Initialize(hInstance) ) { return false; }
		return true;
	}

	LINK HWND CreateLabelW(HWND hwnd, LPCWSTR Text, int X, int Y, int W, int H)
	{
		if (!MaxsiUI_Controls_Initialized) { InitializeMaxsiUI_Controls((HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); }
		// Set the default font for this label!
		//HFONT hFont=CreateFontW (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
		//	OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
		//	DEFAULT_PITCH | FF_SWISS, TEXT("MS Sans Serif"));
		HFONT hFont=CreateFont (13, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, ANSI_CHARSET,
						OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
						DEFAULT_PITCH | FF_SWISS, TEXT("Verdana"));

		HWND NewControl = CreateWindowW(
		L"MaxsiUI_Control_LabelW",  // Class; Unicode assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageW(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
			SendMessageW(NewControl, WM_SETTEXT, WPARAM (Text), 0);
		}
		return NewControl;
	}

	LINK HWND CreateLabelA(HWND hwnd, LPCSTR Text, int X, int Y, int W, int H)
	{
		if (!MaxsiUI_Controls_Initialized) { InitializeMaxsiUI_Controls((HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); }
		// Set the default font for this label!
		//HFONT hFont=CreateFontW (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
		//	OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
		//	DEFAULT_PITCH | FF_SWISS, TEXT("MS Sans Serif"));
		HFONT hFont=CreateFont (13, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, ANSI_CHARSET,
						OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
						DEFAULT_PITCH | FF_SWISS, TEXT("Verdana"));

		HWND NewControl = CreateWindowA(
		"MaxsiUI_Control_LabelA",  // Class; Unicode assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageA(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
			SendMessageA(NewControl, WM_SETTEXT, (WPARAM) Text, 0);
		}
		return NewControl;
	}

	

	LINK HWND CreateLabelAEx(HWND hwnd, LPCSTR Text, int X, int Y, int W, int H, HFONT hFont)
	{
		if (!MaxsiUI_Controls_Initialized) { InitializeMaxsiUI_Controls((HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE)); }

		HWND NewControl = CreateWindowA(
		"MaxsiUI_Control_LabelA",  // Class; Unicode assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageA(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
			SendMessageA(NewControl, WM_SETTEXT, (WPARAM) Text, 0);
		}
		return NewControl;
	}

	LINK HWND CreateButtonW(HWND hwnd, LPCWSTR Text, int X, int Y, int W, int H)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontW (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, L"MS Sans Serif");

		HWND NewControl = CreateWindowW(
		L"BUTTON",  // Class; Unicode assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageW(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}

	LINK HWND CreateButtonA(HWND hwnd, LPCSTR Text, int X, int Y, int W, int H)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontA (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, "MS Sans Serif");

		HWND NewControl = CreateWindowA(
		"BUTTON",  // Class; Unicode assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageA(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}



	LINK HWND CreateTextW(HWND hwnd, LPCWSTR Text, int X, int Y, int W, int H)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontW (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, L"MS Sans Serif");

		HWND NewControl = CreateWindowExW(
		WS_EX_CLIENTEDGE,
		L"EDIT",  // Class; Unicode assumed.
		Text,        // Text
		WS_VISIBLE | WS_CHILD | WS_BORDER |
		ES_LEFT | ES_AUTOHSCROLL,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageW(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}

	LINK HWND CreateTextA(HWND hwnd, LPCSTR Text, int X, int Y, int W, int H)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontA (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, "MS Sans Serif");

		HWND NewControl = CreateWindowExA(
		WS_EX_CLIENTEDGE,
		"EDIT",  // Class; ANSI asumed
		Text,        // Text
		WS_VISIBLE | WS_CHILD | WS_BORDER |
		ES_LEFT | ES_AUTOHSCROLL,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageA(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}

	LINK HWND CreateTextExW(HWND hwnd, LPCWSTR Text, int X, int Y, int W, int H, DWORD Style)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontW (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, L"MS Sans Serif");

		HWND NewControl = CreateWindowExW(
		WS_EX_CLIENTEDGE,
		L"EDIT",  // Class; Unicode assumed.
		Text,        // Text
		Style,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageW(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}

	LINK HWND CreateTextExA(HWND hwnd, LPCSTR Text, int X, int Y, int W, int H, DWORD Style)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontA (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, "MS Sans Serif");

		HWND NewControl = CreateWindowExA(
		WS_EX_CLIENTEDGE,
		"EDIT",  // Class; ANSI asumed
		Text,        // Text
		Style,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageA(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}
	
	LINK char*	GetTextAText(HWND hwnd)
	{
		if (No(hwnd)) { return 0; }

		WORD TEXT_LEN = (WORD)SendMessageA(hwnd,EM_LINELENGTH,(WPARAM) 0,(LPARAM) 0);

		if ( TEXT_LEN == 1 )
		{
			TEXT_LEN = 2; // Hack. TEXT_LEN = 1 makes stuff weird.
		}

		size_t TextBuffer	=	TEXT_LEN+1;

		if ( TextBuffer < sizeof(WORD) )
		{
			TextBuffer	=	sizeof(WORD);
		}

		char*	TEXT	=	new char[TextBuffer];
		memset(TEXT,0,TextBuffer);
		memcpy(TEXT,&TEXT_LEN,sizeof(WORD));
			
		SendMessageA(hwnd,EM_GETLINE,(WPARAM)0,(LPARAM)TEXT);

		TEXT[TEXT_LEN] = 0;

		return TEXT;		
	}
	
	LINK wchar_t*	GetTextWText(HWND hwnd)
	{
		if (No(hwnd)) { return 0; }

		WORD TEXT_LEN = (WORD)SendMessageW(hwnd,EM_LINELENGTH,(WPARAM) 0,(LPARAM) 0);
		wchar_t* TEXT	=	new wchar_t[((TEXT_LEN > sizeof(WORD)) ? TEXT_LEN : sizeof(WORD) / sizeof(wchar_t))+1];
		memset(TEXT,0,TEXT_LEN*sizeof(wchar_t));
		memcpy(TEXT,&TEXT_LEN,sizeof(WORD));
			
		SendMessageW(hwnd,EM_GETLINE,(WPARAM)0,(LPARAM)TEXT);

		TEXT[TEXT_LEN] = 0;

		return TEXT;		
	}

	LINK HWND CreateRadioButtonW(HWND hwnd, LPCWSTR Text, int X, int Y, int W, int H, bool Selected)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontW (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, L"MS Sans Serif");

		HWND NewControl = CreateWindowW(
		L"BUTTON",  // Class; Unicode assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageW(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}

	LINK HWND CreateRadioButtonA(HWND hwnd, LPCSTR Text, int X, int Y, int W, int H, bool Selected)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontA (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, "MS Sans Serif");

		HWND NewControl = CreateWindowA(
		"BUTTON",  // Class; ANSI assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageA(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
			if ( Selected )
			{
				SendMessageA(NewControl, BM_CLICK, (WPARAM)0, (LPARAM)0);
			}
		}
		return NewControl;
	}

	LINK HWND CreateCheckButtonW(HWND hwnd, LPCWSTR Text, int X, int Y, int W, int H, bool Selected)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontW (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, L"MS Sans Serif");

		HWND NewControl = CreateWindowW(
		L"BUTTON",  // Class; Unicode assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageW(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
			if ( Selected )
			{
				Button_SetCheck(NewControl,BST_CHECKED);
			}
		}
		return NewControl;
	}

	LINK HWND CreateCheckButtonA(HWND hwnd, LPCSTR Text, int X, int Y, int W, int H, bool Selected)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontA (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, "MS Sans Serif");

		HWND NewControl = CreateWindowA(
		"BUTTON",  // Class; ANSI assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageA(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
			if ( Selected )
			{
				Button_SetCheck(NewControl,BST_CHECKED);
			}
		}
		return NewControl;
	}

	LINK HWND CreateProgressBarW(HWND hwnd, LPCWSTR Text, int X, int Y, int W, int H)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontW (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, L"MS Sans Serif");

		HWND NewControl = CreateWindowW(
		L"msctls_progress32",  // Class; Unicode assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD | PBS_SMOOTH | PBS_MARQUEE,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageA(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}

	LINK HWND CreateProgressBarA(HWND hwnd, LPCSTR Text, int X, int Y, int W, int H)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontA (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, "MS Sans Serif");

		HWND NewControl = CreateWindowA(
		"msctls_progress32",  // Class; ANSI assumed.
		Text,        // Text will be defined later.
		WS_VISIBLE | WS_CHILD | PBS_SMOOTH | PBS_MARQUEE,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageA(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}

	LINK HWND CreateListViewM(HWND hwnd)
	{
		HWND	NewControl	=	CreateWindowM(
			WC_LISTVIEWM,
			_MESTR(""),
			WS_VISIBLE | WS_CHILD | WS_BORDER | LVS_REPORT | LVS_EDITLABELS,
			0,
			0,
			0,
			0,
			hwnd,
			NULL, // Todo: Menus!
			(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
			NULL);

		return NewControl;
	}

	LINK BOOL AddListViewColumn(HWND List, int Id, MESTR* Name, int Width)
	{
		BOOL		Result	=	TRUE;
		LVCOLUMNW	Column; 

		wchar_t*	Wide	=	MESTRWP(Name); // Convert Name to wchar_t, if it isn't already it.

		Column.mask			=	LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; 
		Column.iSubItem		=	Id;
		Column.cx			=	Width;
		Column.fmt			=	LVCFMT_LEFT;
		Column.pszText		=	Wide;

		if (ListView_InsertColumn(List, Id, &Column) == -1) 
		{
			Result			=	FALSE;
		}

		MESTRUWP(Wide); // Delete Wide if it was converted.

		return Result;
	}

	LINK HWND CreateTreeViewA(HWND hwnd, char* Unused, int X, int Y, int W, int H)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontA (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, "MS Sans Serif");

		HWND NewControl = CreateWindowA(
		WC_TREEVIEWA,  // Class; ANSI assumed.
		"LOLOL",        // Text will be defined later.
		WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLongM(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageA(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}
	LINK HWND CreateTreeViewW(HWND hwnd, char* Unused, int X, int Y, int W, int H)
	{
		// Set the font for all buttons etc:
		HFONT hFont=CreateFontW (10, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
			DEFAULT_PITCH | FF_SWISS, L"MS Sans Serif");

		HWND NewControl = CreateWindowW(
		WC_TREEVIEWW,  // Class; ANSI assumed.
		L"LOLOL",        // Text will be defined later.
		WS_VISIBLE | WS_CHILD | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT,  // Styles.
		X,         // x position. 
		Y,         // y position. 
		W,        // Button width.
		H,        // Button height.
		hwnd,       // Parent window.
		NULL,       // No menu.
		(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE), 
		NULL);      // Pointer not needed.

		if ( NewControl )
		{
			SendMessageW(NewControl, WM_SETFONT, WPARAM (hFont), TRUE);
		}
		return NewControl;
	}

	LINK HTREEITEM AddItemToTreeViewA(HWND hwndTV, LPCSTR lpszItem, int nLevel)
	{ 
		TVITEMA tvi; 
		TVINSERTSTRUCTA tvins; 
		static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST; 
		static HTREEITEM hPrevRootItem = NULL; 
		static HTREEITEM hPrevLev2Item = NULL; 
		//HTREEITEM hti; 

		tvi.mask = TVIF_TEXT | TVIF_IMAGE 
				   | TVIF_SELECTEDIMAGE | TVIF_PARAM; 

		// Set the text of the item.
		char* ItemText = BuildString(1,lpszItem);

		tvi.pszText = ItemText; 
		tvi.cchTextMax = sizeof(tvi.pszText)/sizeof(tvi.pszText[0]); 

		// Assume the item is not a parent item, so give it a 
		// document image. 
		//tvi.iImage = g_nDocument; 
		//tvi.iSelectedImage = g_nDocument; 

		// Save the heading level in the item's application-defined 
		// data area. 
		tvi.lParam = (LPARAM)nLevel; 
		tvins.item = tvi; 
		tvins.hInsertAfter = hPrev; 

		// Set the parent item based on the specified level. 
		if (nLevel == 1) 
			tvins.hParent = TVI_ROOT; 
		else if (nLevel == 2) 
			tvins.hParent = hPrevRootItem; 
		else 
			tvins.hParent = hPrevLev2Item; 

		// Add the item to the tree-view control. 
		hPrev = (HTREEITEM)SendMessageA(hwndTV, 
									   TVM_INSERTITEM, 
									   0,
									   (LPARAM)(LPTVINSERTSTRUCT)&tvins); 

		delete[] ItemText;

		// Save the handle to the item. 
		if (nLevel == 1) 
			hPrevRootItem = hPrev; 
		else if (nLevel == 2) 
			hPrevLev2Item = hPrev; 

		// The new item is a child item. Give the parent item a 
		// closed folder bitmap to indicate it now has child items. 
		//if (nLevel > 1)
		//{ 
		//    hti = TreeView_GetParent(hwndTV, hPrev); 
		//    tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; 
		//    tvi.hItem = hti; 
		//    tvi.iImage = g_nClosed; 
		//    tvi.iSelectedImage = g_nClosed; 
		//    TreeView_SetItem(hwndTV, &tvi); 
		//} 

		return hPrev; 
	} 

	LINK HTREEITEM AddItemToTreeViewW(HWND hwndTV, LPCWSTR lpszItem, int nLevel)
	{ 
		if ( !lpszItem ) { return 0; }
		TVITEMW tvi; 
		TVINSERTSTRUCTW tvins; 
		static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST; 
		static HTREEITEM hPrevRootItem = NULL; 
		static HTREEITEM hPrevLev2Item = NULL; 
		static HTREEITEM hPrevLev3Item = NULL; 
		static HTREEITEM hPrevLev4Item = NULL; 
		static HTREEITEM hPrevLev5Item = NULL; 
		static HTREEITEM hPrevLev6Item = NULL; 
		static HTREEITEM hPrevLev7Item = NULL; 
		static HTREEITEM hPrevLev8Item = NULL; 
		//HTREEITEM hti; 

		tvi.mask = TVIF_TEXT | TVIF_IMAGE 
				   | TVIF_SELECTEDIMAGE | TVIF_PARAM; 

		// Set the text of the item.
		size_t ItemText_Len = wcslen(lpszItem)+1;
		LPWSTR ItemText = new WCHAR[ItemText_Len];
		wcscpy_s(ItemText,ItemText_Len,lpszItem);

		tvi.pszText = (LPWSTR)ItemText; 
		tvi.cchTextMax = sizeof(tvi.pszText)/sizeof(tvi.pszText[0]); 

		// Assume the item is not a parent item, so give it a 
		// document image. 
		//tvi.iImage = g_nDocument; 
		//tvi.iSelectedImage = g_nDocument; 

		// Save the heading level in the item's application-defined 
		// data area. 
		tvi.lParam = (LPARAM)nLevel; 
		tvins.item = tvi; 
		tvins.hInsertAfter = hPrev; 

		// Set the parent item based on the specified level. 
		if (nLevel == 1) 
			tvins.hParent = TVI_ROOT; 
		else if (nLevel == 2) 
			tvins.hParent = hPrevRootItem; 
		else if (nLevel == 3) 
			tvins.hParent = hPrevLev2Item; 
		else if (nLevel == 4) 
			tvins.hParent = hPrevLev3Item; 
		else if (nLevel == 5) 
			tvins.hParent = hPrevLev4Item; 
		else if (nLevel == 6) 
			tvins.hParent = hPrevLev5Item; 
		else if (nLevel == 7) 
			tvins.hParent = hPrevLev6Item; 
		else if (nLevel == 8) 
			tvins.hParent = hPrevLev7Item; 
		else if (nLevel == 9)
			tvins.hParent = hPrevLev8Item;
		else
		{	
			tvins.hParent = hPrevLev8Item;
		}

		// Add the item to the tree-view control. 
		hPrev = (HTREEITEM)SendMessageW(hwndTV, 
									   TVM_INSERTITEM, 
									   0,
									   (LPARAM)(LPTVINSERTSTRUCT)&tvins); 

		delete[] ItemText;

		// Save the handle to the item. 
		if (nLevel == 1) 
			hPrevRootItem = hPrev; 
		else if (nLevel == 2) 
			hPrevLev2Item = hPrev; 
		else if (nLevel == 3) 
			hPrevLev3Item = hPrev; 
		else if (nLevel == 4) 
			hPrevLev4Item = hPrev; 
		else if (nLevel == 5) 
			hPrevLev5Item = hPrev; 
		else if (nLevel == 6) 
			hPrevLev6Item = hPrev; 
		else if (nLevel == 7) 
			hPrevLev7Item = hPrev; 
		else if (nLevel == 8) 
			hPrevLev8Item = hPrev; 

		// The new item is a child item. Give the parent item a 
		// closed folder bitmap to indicate it now has child items. 
		//if (nLevel > 1)
		//{ 
		//    hti = TreeView_GetParent(hwndTV, hPrev); 
		//    tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; 
		//    tvi.hItem = hti; 
		//    tvi.iImage = g_nClosed; 
		//    tvi.iSelectedImage = g_nClosed; 
		//    TreeView_SetItem(hwndTV, &tvi); 
		//} 

		return hPrev; 
	}
}
